///**
// * Copyright (c) 2016-2020 https://github.com/zhaohuatai
// *
// * contact 824069438@qq.com
// *  
// */
//package org.zfes.snowy.auth.shiro.session.validate;
//
//import java.lang.reflect.Method;
//import java.util.Collection;
//import java.util.Collections;
//import java.util.concurrent.Executors;
//import java.util.concurrent.ScheduledExecutorService;
//import java.util.concurrent.ThreadFactory;
//import java.util.concurrent.TimeUnit;
//import java.util.concurrent.atomic.AtomicInteger;
//import org.apache.shiro.session.InvalidSessionException;
//import org.apache.shiro.session.Session;
//import org.apache.shiro.session.mgt.AbstractValidatingSessionManager;
//import org.apache.shiro.session.mgt.DefaultSessionKey;
//import org.apache.shiro.session.mgt.DefaultSessionManager;
//import org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler;
//import org.apache.shiro.session.mgt.SessionKey;
//import org.apache.shiro.session.mgt.SessionValidationScheduler;
//import org.apache.shiro.session.mgt.ValidatingSessionManager;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.util.ReflectionUtils;
//import org.zfes.snowy.auth.shiro.session.repository.IShiroSessionRepository;
//
//public class SnowyExecutorServiceSessionValidationScheduler  implements SessionValidationScheduler, Runnable {
//    //TODO - complete JavaDoc
//
//    /** Private internal log instance. */
//    private static final Logger log = LoggerFactory.getLogger(ExecutorServiceSessionValidationScheduler.class);
//
//    ValidatingSessionManager sessionManager;
//    IShiroSessionRepository shiroSessionRepository;
//    
//    private int validateStepLength=500;
//    private boolean useRedisValidation;
//    
//    private static final String validateMethodName ="validate";
//    
//    private ScheduledExecutorService service;
//    private long interval = DefaultSessionManager.DEFAULT_SESSION_VALIDATION_INTERVAL;
//    private boolean enabled = false;
//    private String threadNamePrefix = "SessionValidationThread-";
//
//    public SnowyExecutorServiceSessionValidationScheduler() {
//        super();
//    }
//
//    public SnowyExecutorServiceSessionValidationScheduler(ValidatingSessionManager sessionManager) {
//        this.sessionManager = sessionManager;
//    }
//
//    public ValidatingSessionManager getSessionManager() {
//        return sessionManager;
//    }
//
//    public void setSessionManager(ValidatingSessionManager sessionManager) {
//        this.sessionManager = sessionManager;
//    }
//
//    public long getInterval() {
//        return interval;
//    }
//
//    public void setInterval(long interval) {
//        this.interval = interval;
//    }
//
//    public boolean isEnabled() {
//        return this.enabled;
//    }
//
//    public void setThreadNamePrefix(String threadNamePrefix) {
//        this.threadNamePrefix = threadNamePrefix;
//    }
//
//    public String getThreadNamePrefix() {
//        return this.threadNamePrefix;
//    }
//
//    /**
//     * Creates a single thread {@link ScheduledExecutorService} to validate sessions at fixed intervals 
//     * and enables this scheduler. The executor is created as a daemon thread to allow JVM to shut down
//     */
//    //TODO Implement an integration test to test for jvm exit as part of the standalone example
//    // (so we don't have to change the unit test execution model for the core module)
//    public void enableSessionValidation() {
//        if (this.interval > 0l) {
//            this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {  
//	            private final AtomicInteger count = new AtomicInteger(1);
//
//	            public Thread newThread(Runnable r) {  
//	                Thread thread = new Thread(r);  
//	                thread.setDaemon(true);  
//	                thread.setName(threadNamePrefix + count.getAndIncrement());
//	                return thread;  
//	            }  
//            });                  
//            this.service.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS);
//        }
//        this.enabled = true;
//    }
//
//    public void run() {
//    	
//        if (log.isDebugEnabled()) {
//            log.debug("Executing session validation...");
//        }
//        long startTime = System.currentTimeMillis();
//        if(useRedisValidation) {
//        	this.doSessionsValidate();
//        }else {
//        	this.sessionManager.validateSessions();
//        }
//        long stopTime = System.currentTimeMillis();
//        if (log.isDebugEnabled()) {
//            log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds.");
//        }
//    }
//
//    public void disableSessionValidation() {
//        if (this.service != null) {
//            this.service.shutdownNow();
//        }
//        this.enabled = false;
//    }
//    
//    protected void  doSessionsValidate(){
//    	long size = validateStepLength;
//    	long start=0;
//    	long end=size+start;
//    	Collection<Session> sessionList = shiroSessionRepository.getSessionInSegment(start, end);
//    	 while(sessionList!=null&&!sessionList.isEmpty()) {
//    		 int invalidCount = 0;
//             for(Session session : sessionList) {
//                 try {
//                	 if(session!=null){
//                		 doOneSessionValidate( session);
//                	 }
//                 } catch (InvalidSessionException e) {
//                	 invalidCount++;
//                 }
//             }
//             start = start + size - invalidCount;
//             sessionList = Collections.emptyList();
//         }
//    	
//    }
//    
//    protected void  doOneSessionValidate(Session session){
//    	Method validateMethod = ReflectionUtils.findMethod(AbstractValidatingSessionManager.class, validateMethodName, Session.class, SessionKey.class);
//        validateMethod.setAccessible(true);
//        ReflectionUtils.invokeMethod(validateMethod, sessionManager, session, new DefaultSessionKey(session.getId()));
//    }
//
//	public boolean isUseRedisValidation() {
//		return useRedisValidation;
//	}
//
//	public void setUseRedisValidation(boolean useRedisValidation) {
//		this.useRedisValidation = useRedisValidation;
//	}
//
//	public IShiroSessionRepository getShiroSessionRepository() {
//		return shiroSessionRepository;
//	}
//
//	public void setShiroSessionRepository(IShiroSessionRepository shiroSessionRepository) {
//		this.shiroSessionRepository = shiroSessionRepository;
//	}
//
//	
//    
//}
